﻿using System;
using System.Collections;
using System.Collections.Generic;
using CalcSharp.Core.Containers;
using CalcSharp.Core.Plugin;
using System.Security.Cryptography;
using CalcSharp.Core;

namespace plug_crand
{
    public class CRand: ICMDPlugin
    {
        private IPluginHost host;

        public Tresult Run(ArrayList parameters)
        {
            Tresult ret = new Tresult();
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            string cmd = Convert.ToString(parameters[0]);
            byte[] randombytes;
            switch (cmd.ToUpper())
            {
                case "BYTE":
                    randombytes = new byte[1];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = randombytes[1];
                    break;
                case "SBYTE":
                    randombytes = new byte[1];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = (sbyte)randombytes[1];
                    break;
                case "SHORT":
                    randombytes = new byte[2];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = BitConverter.ToInt16(randombytes, 0);
                    break;
                case "USHORT":
                    randombytes = new byte[2];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = BitConverter.ToUInt16(randombytes, 0);
                    break;
                case "INT":
                    randombytes = new byte[4];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = BitConverter.ToInt32(randombytes, 0);
                    break;
                case "UINT":
                    randombytes = new byte[4];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = BitConverter.ToUInt32(randombytes, 0);
                    break;
                case "LONG":
                    randombytes = new byte[8];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = BitConverter.ToInt64(randombytes, 0);
                    break;
                case "ULONG":
                    randombytes = new byte[8];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = BitConverter.ToUInt64(randombytes, 0);
                    break;
                case "FLOAT":
                    randombytes = new byte[4];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = BitConverter.ToSingle(randombytes, 0);
                    break;
                case "DOUBLE":
                    randombytes = new byte[8];
                    rng.GetBytes(randombytes);
                    ret.floatingpt = BitConverter.ToDouble(randombytes, 0);
                    break;
                default:
                    throw new CSException("Unsuported data type");
            }
            return ret;
        }

        public string Name
        {
            get { return "CRAND"; }
        }

        public Dictionary<string, string> autocomplete
        {
            get { return null; }
        }

        public string Help
        {
            get { throw new NotImplementedException(); }
        }

        public IPluginHost Host
        {
            get
            {
                return this.host;
            }
            set
            {
                this.host = value;
                this.host.Register(this);
            }
        }
    }
}
